﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PPT = Microsoft.Office.Interop.PowerPoint;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Threading;

namespace An_Im.Core
{
    /// <summary>
    /// 插件库的消息处理器。
    /// </summary>
    static class GlobalMessageStateUpdater
    {
        private static Thread _originThread = null; // 源线程
        private static Thread _thread = null; // 当前分支线程。
        private static int _presHashCode = 0; // 演示文稿的哈希值。
        private static int _sldHashCode = 0; // 幻灯片的哈希值。
        private static int _seqcState = 0; // 动画窗格状态值。
        private static bool[] _changedMessagesArray;
        private static bool _active = false;
        private static PPT.Application app;

        /// <summary>
        /// 幻灯片改变时触发该事件。
        /// </summary>
        public static event EventHandler SlideChanged;

        /// <summary>
        /// 动画序列改变的时候触发该事件（优先级最高）。
        /// </summary>
        public static event EventHandler SequenceChanged;

        /// <summary>
        /// 演示文稿改变时触发该事件。
        /// </summary>
        public static event EventHandler PresentationChanged;

        public static void Initialize(PPT.Application application)
        {
            _originThread = Thread.CurrentThread;
            _changedMessagesArray = new bool[3];
            _thread = new Thread(Update);
            app = application;
            app.SlideShowBegin += App_SlideShowBegin; // 放映时关闭对演示文稿的监听。
            app.SlideShowEnd += App_SlideShowEnd; // 结束放映时重新开始对演示文稿的监听。
            app.PresentationBeforeClose += App_PresentationBeforeClose;
        }

        private static void App_PresentationBeforeClose(PPT.Presentation Pres, ref bool Cancel)
        {
            AbortListen();
        }

        private static void App_SlideShowEnd(PPT.Presentation Pres)
        {
            ContinueListen();
        }

        private static void App_SlideShowBegin(PPT.SlideShowWindow Wn)
        {
            StopListen();
        }

        /// <summary>
        /// 开始监视当前 PowerPoint 程序的状态。
        /// </summary>
        public static void StartListen()
        {
            if (_thread != null)
            {
                _active = true;
                _thread.Start();
            }

        }


        /// <summary>
        /// 暂停监听
        /// </summary>
        public static void StopListen()
        {
            _active = false;
        }

        /// <summary>
        /// 继续监听
        /// </summary>
        public static void ContinueListen()
        {
            _active = true;
        }

        /// <summary>
        /// 结束监视当前 PowerPoint 程序的状态。
        /// </summary>
        public static void AbortListen()
        {
            if (_thread != null)
            {
                _active = false;
                _thread.Abort();
            }
        }

        /// <summary>
        /// 获得当前程序状态。
        /// </summary>
        public static void Update()
        {
            while (true)
            {
                try
                {
                    if (_active == false)
                    {
                        Thread.Sleep(250);
                        continue;
                    }
                    var seqcState = 0;

                    PPT.Presentation pres = null;
                    PPT.Slide sld = null;
                    PPT.Sequence seqc = null;
                    int prescount = 0;
                    prescount = app.Presentations.Count;

                    // 情形1：无演示文稿，什么都不做……
                    if (prescount == 0)
                    {
                        // Do Nothing
                    }
                    else // 情形2：存在演示文稿
                    {
                        pres = app.ActivePresentation;

                        if (pres.Slides.Count == 0) // 无幻灯片时
                        {
                            // Do Nothing
                        }
                        else // 有幻灯片时
                        {
                            sld = CoreManipulator.GetSlideInGeneralOccassion();
                            if (sld == null) // 无幻灯片时。
                            {
                                // Do Nothing
                            }
                            else // 有幻灯片时
                            {
                                // 无外部 UI 事件时计算该内容。
                                if (_changedMessagesArray[(int)UIChangedMessage.AnimationSequenceChanged] == false)
                                {
                                    seqc = sld.TimeLine.MainSequence;
                                    seqcState = seqc.Count;
                                    //var factor = -1;
                                    for (int i = 1; i <= seqc.Count; i++)
                                    {
                                        seqcState += GetAnimEffect(seqc[i]);
                                        //factor = -factor;
                                    }

                                }

                            }
                        }
                    }


                    if (_seqcState != seqcState || _changedMessagesArray[(int)UIChangedMessage.AnimationSequenceChanged] == true)
                    {
                        SequenceChanged?.Invoke(null, EventArgs.Empty);
                    }


                    // 保存当前上下文
                    _seqcState = seqcState;
                    for (int i = 0; i < 3; i++)
                        _changedMessagesArray[i] = false;
                }
                catch
                {

                }
                Thread.Sleep(250); // 进程延时

            }

        }

        private static int GetAnimEffect(PPT.Effect eff)
        {
            try
            {
                return (int)eff.EffectType;
            }
            catch
            {
                return -1;
            }


        }


        /// <summary>
        /// 引发动画序列变化事件。
        /// </summary>
        public static void RaiseAnimationSequenceMessage()
        {
            _changedMessagesArray[(int)UIChangedMessage.AnimationSequenceChanged] = true;
        }

        public static void RaiseMessage(UIChangedMessage message)
        {
            _changedMessagesArray[(int)message] = true;
        }

    }
}
